package com.ztesoft.web.common;

import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;import org.apache.commons.net.ftp.FTPClient;import org.apache.commons.net.ftp.FTPFile;import org.apache.log4j.Logger;import org.apache.log4j.spi.ErrorCode;import com.ztesoft.framework.exception.BaseAppException;import com.ztesoft.framework.exception.ExceptionHandler;import com.ztesoft.framework.util.Utils;

/**
 * <p>Title: Prodigy</p>
 *
 * <p>Description: BSNWeb</p>
 *
 * <p>Copyright: Copyright (c) 2005</p>
 *
 * <p>Company: ZTEsoft</p>
 *
 * @author ying.rui@zte.com.cn
 * @version 1.0
 */
public class FtpClientHelper {

    private static String FILE_POSTFIX_ALL = "*";

    /** 日志 */
    public static final Logger logger = Logger.getLogger(FtpClientHelper.class);

    private FtpClientHelper() {
    }

    /**
     * 建立FTP连接
     * @param ip String  ftp Server ip地址
     * @param port int   ftp Server port端口
     * @param user String  ftp Server 用户名
     * @param password String  ftp Server 口令
     * @return FTPClient 一个ftp链接
     * @throws BaseAppException
     */
    public static FTPClient openFtpServer(String ip, int port, String user, String password) throws BaseAppException {
        if (ip == null || ip.length() < 1 || user == null || user.length() < 1 || password == null) {
            throw ExceptionHandler.publish("参数异常");
        }

        try {
            FTPClient ftpClient = new FTPClient();
            ftpClient.connect(ip, port);
            ftpClient.login(user, password);
            return ftpClient;
        } catch (IOException ex) {
            throw ExceptionHandler.publish("FTP_IO_ERR", ex);
        }
    }

    /**
     * 进入远程SERVER目录
     * @param ftpClient FTPClient  一个ftp链接
     * @param remotePath String 路径
     * @return boolean 是否成功
     * @throws BaseAppException 异常
     */
    public static boolean gotoRemotePath(FTPClient ftpClient, String remotePath) throws BaseAppException {
        if (ftpClient == null || remotePath == null || remotePath.length() < 1) {

        }
        //是否链接了
        if (!ftpClient.isConnected()) {
            throw ExceptionHandler.publish("FTP_IS_DISCONNECTED FAILED");
        }
        try {
            return ftpClient.changeWorkingDirectory(remotePath);
        } catch (IOException ex) {
            throw ExceptionHandler.publish("FTP_IO_ERR", ex);
        }
    }

    /**
     * 下载文件
     * @param ftpClient FTPClient   一个ftp链接
     * @param reomteFileName String 远程获取的文件名字
     * @param localFilePathName String 本地文件名字（含路径）
     * @return boolean 成功标识
     * @throws BaseAppException 异常
     */
    public static boolean getFile(FTPClient ftpClient, String reomteFileName, String localFilePathName) throws
            BaseAppException {
        if (ftpClient == null || reomteFileName == null || reomteFileName.length() < 1 || localFilePathName == null ||
            localFilePathName.length() < 1) {
            throw ExceptionHandler.publish("FTP_PARAM_ERR");
        }
        //是否链接了
        if (!ftpClient.isConnected()) {
            throw ExceptionHandler.publish("FTP_IS_DISCONNECTED");
        }
        try {
            File file = new File(localFilePathName);
            FileOutputStream fos = new FileOutputStream(file);
            boolean bFlag = ftpClient.retrieveFile(reomteFileName, fos);
            fos.close();
            return bFlag;
        } catch (IOException ex) {
            throw ExceptionHandler.publish("FTP_IO_ERR", ex);
        }
    }

    /**
     * 获取远程ftp服务器一个目录下的文件,不包含这个目录下的子目录
     * @param ftpClient FTPClient   一个ftp链接
     * @param localFilePathName String 本地保存文件的路径
     * @param deleteRemoteFileFlag boolean 删除远程文件的标志 true 删除，false 保留
     * @param filePostfix String 文件后缀(区分大小写) * 所有的文件
     * @return int 返回文件的个数
     * @throws BaseAppException 异常
     */
    public static int getDirFiles(FTPClient ftpClient, String localFilePathName,
                                  boolean deleteRemoteFileFlag, String filePostfix) throws
            BaseAppException {
        if (ftpClient == null || Utils.isEmpty(localFilePathName) || Utils.isEmpty(filePostfix)) {
            throw ExceptionHandler.publish("FTP_PARAM_ERR");
        }
        //是否链接了
        if (!ftpClient.isConnected()) {
            throw ExceptionHandler.publish("FTP_IS_DISCONNECTED");
        }
        try {
            FTPFile[] ftpFileArr = ftpClient.listFiles();
            if (Utils.isEmpty(ftpFileArr)) {
                return 0;
            }
            int fileNumber = 0;
            for (int i = 0; i < ftpFileArr.length; i++) {
                if (ftpFileArr[i].isFile()
                    && (filePostfix.equals(FILE_POSTFIX_ALL)
                        || ftpFileArr[i].getName().indexOf(filePostfix) > -1)){

                    File file = new File(localFilePathName + "/" + ftpFileArr[i].getName());
                    FileOutputStream fos = new FileOutputStream(file);
                    boolean bFlag = ftpClient.retrieveFile(ftpFileArr[i].getName(), fos);
                    fos.close();
                    if (bFlag) fileNumber++;
                    if (deleteRemoteFileFlag) {
                        ftpClient.deleteFile(ftpFileArr[i].getName());
                    }
                }
            }

            return fileNumber;
        } catch (Exception ex) {
            throw ExceptionHandler.publish("FTP_IO_ERR", ex);
        }
    }


    /**
     * 从ftpserver上删除指定文件
     * @param ftpClient FTPClient   一个ftp链接
     * @param reomteFileName String 远程获取的文件名字
     * @return boolean 成功标识
     * @throws BaseAppException 异常
     */
    public static boolean deleteFile(FTPClient ftpClient, String reomteFileName) throws
            BaseAppException {
        if (ftpClient == null || reomteFileName == null || reomteFileName.length() < 1) {
            throw ExceptionHandler.publish("FTP_PARAM_ERR");
        }
        //是否链接了
        if (!ftpClient.isConnected()) {
            throw ExceptionHandler.publish("FTP_IS_DISCONNECTED");
        }
        try {
            boolean bFlag = ftpClient.deleteFile(reomteFileName);
            return bFlag;
        } catch (IOException ex) {
            throw ExceptionHandler.publish("FTP_IO_ERR", ex);
        }
    }


    /**
     * 上传文件
     * @param ftpClient FTPClient  一个ftp链接
     * @param remoteFileName String 远程文件名字
     * @param localPathFileName String 本地文件名字（含路径）
     * @return boolean 成功标识
     * @throws BaseAppException 异常
     */
    public static boolean putFile(FTPClient ftpClient, String remoteFileName, String localPathFileName) throws
            BaseAppException {
        if (ftpClient == null || remoteFileName == null || remoteFileName.length() < 1 || localPathFileName == null ||
            localPathFileName.length() < 1) {
            throw ExceptionHandler.publish("FTP_PARAM_ERR");
        }
        //是否链接了
        if (!ftpClient.isConnected()) {
            throw ExceptionHandler.publish("FTP_IS_DISCONNECTED");
        }
        try {
            // 以二进制传输文件
            ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
            
            File file = new File(localPathFileName);
            FileInputStream fis = new FileInputStream(file);
            boolean bFlag = ftpClient.appendFile(remoteFileName, fis);
            fis.close();
            return bFlag;
        } catch (IOException ex) {
            throw ExceptionHandler.publish("FTP_IO_ERR", ex);
        }
    }
    
    /**
     * 指定传输模式上传文件
     * 
     * @param ftpClient
     * @param remoteFileName
     * @param localPathFileName
     * @param transStyle
     * @return
     * @throws BaseAppException
     */
    public static boolean putFile(FTPClient ftpClient, String remoteFileName, String localPathFileName, String transStyle)
            throws BaseAppException
    {
        if (ftpClient == null || remoteFileName == null || remoteFileName.length() < 1 || localPathFileName == null
                || localPathFileName.length() < 1)
        {
            throw ExceptionHandler.publish("FTP_PARAM_ERR");
        }
        // 是否链接了

        if (!ftpClient.isConnected())
        {
            throw ExceptionHandler.publish("FTP_IS_DISCONNECTED");
        }
        try
        {
            // 以二进制传输文件
            if (transStyle.equals("binary"))
            {
                ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
            }

            File file = new File(localPathFileName);
            FileInputStream fis = new FileInputStream(file);
            boolean bFlag = ftpClient.appendFile(remoteFileName, fis);
            fis.close();
            return bFlag;
        }
        catch (IOException ex)
        {
            throw ExceptionHandler.publish("FTP_IO_ERR", ex);
        }
    }


    /**
     * 关闭链接
     * @param ftpClient FTPClient   一个ftp链接
     * @throws BaseAppException 异常
     */
    public static void closeFtpServver(FTPClient ftpClient) throws BaseAppException {
        try {
            ftpClient.disconnect();
            ftpClient = null;
        } catch (IOException ex) {
            throw ExceptionHandler.publish("FTP_IO_ERR", ex);
        }
    }

    public static void main(String[] args) throws BaseAppException {
        FTPClient ftpClient = new FTPClient();
        try {
            //打开链接
            ftpClient = FtpClientHelper.openFtpServer("134.201.26.153", 21, "gxbsn", "gxbsn123");
            //进入远程目录
            FtpClientHelper.gotoRemotePath(ftpClient, "/file/procfile/zhangjing");

            //上载文件（改名）
            //FtpClientHelper.putFile(ftpClient, "xyz", "D:/log/error.log");

            //下载文件
//            FtpClientHelper.getFile(ftpClient,"a.txt","d:/a.txt");
            //删除文件
            FtpClientHelper.deleteFile(ftpClient,"a.txt");

            //下载服务器端指定目录下的所有文件
//            int fileNumber = FtpClientHelper.getDirFiles(ftpClient, "d:/", true,"*");
//            System.out.println(fileNumber);

        } finally {
            //一定要关闭链接
            FtpClientHelper.closeFtpServver(ftpClient);
        }
    }

    /**
     * 获取远程ftp服务器一个目录下的文件,不包含这个目录下的子目录
     * @param ftpClient FTPClient   一个ftp链接
     * @param localFilePathName String 本地保存文件的路径
     * @param deleteRemoteFileFlag boolean 删除远程文件的标志 true 删除，false 保留
     * @param filePostfix String 文件后缀(区分大小写) * 所有的文件
     * @return int 返回文件的个数
     * @throws BaseAppException 异常
     */
    public static int getDirFiles(FTPClient ftpClient, String localFilePathName,
                                  boolean deleteRemoteFileFlag, String filePostfix, String fileBegin) throws
            BaseAppException {
        if (ftpClient == null || Utils.isEmpty(localFilePathName) || Utils.isEmpty(filePostfix)) {
            throw ExceptionHandler.publish("FTP_PARAM_ERR");
        }
        //是否链接了
        if (!ftpClient.isConnected()) {
            throw ExceptionHandler.publish("FTP_IS_DISCONNECTED");
        }
        try {
            //FTPFile[] ftpFileArr = ftpClient.listFiles();
        	String[] ftpFileNameArr = ftpClient.listNames();
            if (Utils.isEmpty(ftpFileNameArr)) {
            	logger.error("-------------no file----------");
                return 0;
            }
            int fileNumber = 0;
            for (int i = 0; i < ftpFileNameArr.length; i++) {
            	logger.error("---------------file name:" + ftpFileNameArr[i]);
                if (//ftpFileArr[i].isFile() && 
                		(filePostfix.equals(FILE_POSTFIX_ALL)
                        || ftpFileNameArr[i].indexOf(filePostfix) > -1)
                        && ftpFileNameArr[i].indexOf(fileBegin) > -1){

                    File file = new File(localFilePathName + "/" + ftpFileNameArr[i]);
                    FileOutputStream fos = new FileOutputStream(file);
                    boolean bFlag = ftpClient.retrieveFile(ftpFileNameArr[i], fos);
                    fos.close();
                    if (bFlag) fileNumber++;
                    if (deleteRemoteFileFlag) {
                        ftpClient.deleteFile(ftpFileNameArr[i]);
                    }
                }
            }

            return fileNumber;
        } catch (Exception ex) {
            throw ExceptionHandler.publish("FTP_IO_ERR", ex);
        }
    }

    
    /**
     * 从ftpserver上重命名文件
	 * add by wang.minxin 2012-02-18
	 * 
     * @param ftpClient FTPClient   一个ftp链接
     * @param fromReomteFileName String 远程获取的文件名字
     * @param toReomteFileName String 远程获取的文件重命名后的名字

     * @return boolean 成功标识
     * @throws BaseAppException 异常
     */
    public static boolean renameFile(FTPClient ftpClient, String fromReomteFileName, String toReomteFileName) throws
            BaseAppException {
        if (ftpClient == null || fromReomteFileName == null || fromReomteFileName.length() < 1
        		|| toReomteFileName == null || toReomteFileName.length() < 1) {
            throw ExceptionHandler.publish("FTP_PARAM_ERR");
        }
        //是否链接了

        if (!ftpClient.isConnected()) {
            throw ExceptionHandler.publish("FTP_IS_DISCONNECTED");
        }
        try {
            boolean bFlag = ftpClient.rename(fromReomteFileName, toReomteFileName);
            return bFlag;
        } catch (IOException ex) {
            throw ExceptionHandler.publish("FTP_IO_ERR", ex);
        }
    }


}
